const MongoClient = require("mongodb").MongoClient;
const logHandler = require('../component/logHandler');
const MongodbConfig = require('../config/MongodbConfig');

module.exports = {

  /**
   * 创建集合
   * @param {*} collection 
   */
  createCollection(collection) {
    MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url,
      MongodbConfig.MONGODB_CONNECTION_INFO.database, collection, (err, client) => {
        client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).createCollection(collection).then(
          function (result) {
            logHandler.info(`集合${collection}创建成功`);
            // 关闭数据库连接
            client.close();
          },
          function (err) {
            logHandler.warn(`集合${collection}创建失败，失败原因：` + err.message);
            // 关闭数据库连接
            client.close();
          }
        )
      })
  },
  /**
   * 获取所有集合
   */
  listCollections() {
    MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url,
      MongodbConfig.MONGODB_CONNECTION_INFO.database, (err, client) => {
        client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).listCollections().toArray().then(
          function (tables) {
            // 关闭数据库连接
            client.close();
            logHandler.info('集合名称如下：');
            tables.forEach(function (value, index, ts) {
              logHandler.info(value.name);
            })
          },
          function (err) {
            // 关闭数据库连接
            client.close();
            logHandler.warn('获取所有集合失败，失败原因：' + err.message);
          })
      });
  },
  /**
   * 向集合中插入数据
   * @param {*} collection 
   * @param {*} document 
   */
  insertDocument(collection, document) {
    let _this = this;
    MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url,
      MongodbConfig.MONGODB_CONNECTION_INFO.database, collection, (err, client) => {
        let that = _this;
        client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).collection(collection).insertOne(document).then(
          function (result) {
            logHandler.info(`向数据库${MongodbConfig.MONGODB_CONNECTION_INFO.database}的集合${collection}中` +
              `插入文档${JSON.stringify(document)}成功`);
            // 关闭数据库连接
            client.close();
          },
          function (err) {
            logHandler.warn(`向数据库${database}的集合${collection}中` +
              `插入文档${JSON.stringify(document)}失败，失败原因：` + err.message);
            // 关闭数据库连接
            client.close();
          })
      });
  },
  /**
   * 向集合中批量插入数据
   * @param {*} collection 
   * @param {*} documentList 
   */
  insertDocumentList(collection, documentList) {
    let _this = this;
    MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url,
      MongodbConfig.MONGODB_CONNECTION_INFO.database, collection, (err, client) => {
        const collection = client.db(database).collection(collection);
        if (documentList) {
          for (let index in documentList) {
            let that = _this;
            collection.insertOne(documentList[index]).then(
              function (result) {
                logHandler.info(`向数据库${database}的集合${collection}中` +
                  `插入文档${JSON.stringify(documentList[index])}成功`);
                // 关闭数据库连接
                client.close();
              },
              function (err) {
                logHandler.warn(`向数据库${database}的集合${collection}中` +
                  `插入文档${JSON.stringify(documentList[index])}失败，失败原因：` + err.message);
                // 关闭数据库连接
                client.close();
              })
          }
        } else {
          logHandler.warn('documentList参数为空')
        }
      })
  },
  /**
   * 获取集合中所有数据
   * @param {*} collection 
   */
  findAllDocument(collection) {
    let _this = this;
    return new Promise((resolve, reject) => {
      let that = _this;
      MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url, (err, client) => {
        return new Promise((resolve, reject) => {
          client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).collection(collection).find({}).toArray().then(
            (result) => {
              // 关闭数据库连接
              client.close();
              resolve(result);
            },
            (err) => {
              logHandler.warn('获取集合中所有数据失败，失败原因：' + err.message);
              // 关闭数据库连接
              client.close();
            }
          )
        }).then((result) => {
          resolve(result);
        });
      });
    });
  },
  /**
   * 修改数据。先查询，再修改
   * @param {*} collection 
   * @param {*} document 
   */
  updateDocument(collection, mongodbUpdator) {
    let _this = this;
    return new Promise(async (resolve, reject) => {
      let that = _this;
      MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url,
        MongodbConfig.MONGODB_CONNECTION_INFO.database, collection, async (err, client) => {
          // 查询
          let document = await new Promise((resolve, reject) => {
            client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).collection(collection).find(mongodbUpdator.key, {}).toArray(
              function (err, result) {
                if (err) {
                  logHandler.warn(`查找stock_info记录失败：${err}`);
                }
                if (null == err && result && result.length == 1) {
                  resolve(result[0])
                } else {
                  resolve(null);
                }
              }
            );
          }).then((_result) => {
            return _result;
          });

          // 更新参数
          let mongodbSetter = mongodbUpdator.mongodbSetter;
          let newDocument = {
            ...document,
            ...mongodbSetter['@set']
          };

          // 更新
          return new Promise((resolve, reject) => {
            client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).collection(collection)
            .update(mongodbUpdator.key, newDocument, mongodbUpdator.options).then(
              (result) => {
                // 关闭数据库连接
                client.close();
                resolve(result.result);
              },
              (err) => {
                logHandler.warn('更新集合中数据失败，失败原因：' + err.message);
                // 关闭数据库连接
                client.close();
              }
            )
          }).then((result) => {
            resolve(result);
          });
        });
    });
  },
  /**
   * 按条件查询
   * @param {*} collection 
   * @param {*} document 
   */
  findDocument(collection, document) {
    let _this = this;
    return new Promise((resolve, reject) => {
      let that = _this;
      MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url,
        MongodbConfig.MONGODB_CONNECTION_INFO.database, collection, (err, client) => {
          return new Promise((resolve, reject) => {
            client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).collection(collection).find(document, {}).toArray(
              function (err, result) {
                if (err) {
                  logHandler.warn(`查找stock_info记录失败：${err}`);
                }
                // 关闭数据库连接
                client.close();
                if (null == err && result && result.length == 1) {
                  resolve(result)
                } else {
                  resolve(null);
                }
              }
            );
          }).then((_result) => {
            resolve(_result);
          });
        });
    });
  },
  /**
   * 删除数据
   * @param {*} collection 
   * @param {*} document 
   */
  deleteDocument(collection, document) {
    let _this = this;
    return new Promise((resolve, reject) => {
      let that = _this;
      MongoClient.connect(MongodbConfig.MONGODB_CONNECTION_INFO.url,
        MongodbConfig.MONGODB_CONNECTION_INFO.database, collection, (err, client) => {
          return new Promise((resolve, reject) => {
            client.db(MongodbConfig.MONGODB_CONNECTION_INFO.database).collection(collection).deleteMany(document).then(
              function (result) {
                resolve(result.result);
                // 关闭数据库连接
                client.close();
              },
              function (err) {
                reject(err);
                // 关闭数据库连接
                client.close();
              }
            );
          }).then((_result) => {
            resolve(_result);
          }, (err) => {
            reject(err);
          });
        });
    });
  },
};